﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Resources;
using System.Reflection;
using System.Globalization;
using System.Windows.Data;

namespace TicketServer.Interfaces.Attributes
{
	/// <summary>
	/// Attribute for localization.
	/// </summary>
	/// <remarks>
	/// Got from http://www.codeproject.com/KB/WPF/FriendlyEnums.aspx
	/// </remarks>
	[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
	public sealed class LocalizableDescriptionAttribute : DescriptionAttribute
	{
		#region Public methods.
		// ------------------------------------------------------------------

		/// <summary>
		/// Initializes a new instance of the 
		/// <see cref="LocalizableDescriptionAttribute"/> class.
		/// </summary>
		/// <param name="description">The description.</param>
		/// <param name="resourcesType">Type of the resources.</param>
		public LocalizableDescriptionAttribute
		(string description, Type resourcesType)
			: base(description)
		{
			_resourcesType = resourcesType;
		}

		#endregion

		#region Public properties.

		/// <summary>
		/// Get the string value from the resources.
		/// </summary>
		/// <value></value>
		/// <returns>The description stored in this attribute.</returns>
		public override string Description
		{
			get
			{
				if (!_isLocalized)
				{
					ResourceManager resMan =
						 _resourcesType.InvokeMember(
						 @"ResourceManager",
						 BindingFlags.GetProperty | BindingFlags.Static |
						 BindingFlags.Public | BindingFlags.NonPublic,
						 null,
						 null,
						 new object[] { }) as ResourceManager;

					CultureInfo culture =
						 _resourcesType.InvokeMember(
						 @"Culture",
						 BindingFlags.GetProperty | BindingFlags.Static |
						 BindingFlags.Public | BindingFlags.NonPublic,
						 null,
						 null,
						 new object[] { }) as CultureInfo;

					_isLocalized = true;

					if (resMan != null)
					{
						DescriptionValue =
							 resMan.GetString(DescriptionValue, culture);
					}
				}

				return DescriptionValue;
			}
		}
		#endregion

		#region Private variables.

		private readonly Type _resourcesType;
		private bool _isLocalized;

		#endregion
	}

	/// <summary>
	/// This class simply takes an enum and uses some reflection to obtain
	/// the friendly name for the enum. Where the friendlier name is
	/// obtained using the LocalizableDescriptionAttribute, which holds the localized
	/// value read from the resource file for the enum
	/// </summary>
	[ValueConversion(typeof(object), typeof(String))]
	public class EnumToFriendlyNameConverter : IValueConverter
	{
		#region IValueConverter implementation

		/// <summary>
		/// Convert value for binding from source object
		/// </summary>
		public object Convert(object value, Type targetType,
				object parameter, CultureInfo culture)
		{
			// To get around the stupid WPF designer bug
			if (value != null)
			{
				FieldInfo fi = value.GetType().GetField(value.ToString());

				// To get around the stupid WPF designer bug
				if (fi != null)
				{
					var attributes =
						(LocalizableDescriptionAttribute[])
			fi.GetCustomAttributes(typeof
			(LocalizableDescriptionAttribute), false);

					return ((attributes.Length > 0) &&
							(!String.IsNullOrEmpty(attributes[0].Description)))
							   ?
								   attributes[0].Description
							   : value.ToString();
				}
			}

			return string.Empty;
		}

		/// <summary>
		/// ConvertBack value from binding back to source object
		/// </summary>
		public object ConvertBack(object value, Type targetType,
			object parameter, CultureInfo culture)
		{
			throw new Exception("Cant convert back");
		}
		#endregion
	}
}
